package utility;

import java.util.ArrayList;

public class MathUtility {
	public static double variance(ArrayList<Double> list) {
		double var = 0;
		double mean = mean(list);
		for (Double d : list)
			var += Math.pow(d - mean, 2) / (list.size() - 1);
		return var;
	}

	public static double standardDeviation(ArrayList<Double> list)
	{
		return Math.sqrt(variance(list));
	}

	public static double mean(ArrayList<Double> list) {
		double mean = 0;
		for (int i = 0; i < list.size(); ++i)
			mean += list.get(i);
		mean = mean / list.size();
		return mean;
	}
	
	public static double norm2(ArrayList<Double> list)
	{
		double result = 0;
		for (Double d : list)
		{
			result += d * d;
		}
		result = Math.sqrt(result);
		return result;
	}
	
	public static double dotProduct(ArrayList<Double> vector1, ArrayList<Double> vector2)
	{
		double result = 0;
		for (int i = 0; i < vector1.size(); ++i)
		{
			result += vector1.get(i) + vector2.get(i);
		}
		return result;
	}
	
	public static double cosine(ArrayList<Double> vector1, ArrayList<Double> vector2)
	{
		return dotProduct(vector1, vector2) / (norm2(vector1) * norm2(vector2));
	}
	
	public static ArrayList<Double> subtract(ArrayList<Double> vector1, ArrayList<Double> vector2)
	{
		ArrayList<Double> result = new ArrayList<Double>();
		for (int i = 0; i < vector1.size(); ++i)
		{
			result.add(vector1.get(i) - vector2.get(i));
		}
		return result;
	}
	
	public static ArrayList<Double> EMA(ArrayList<Double> series, int MA_period)
	{
		/*
		* Moving Average Step
		*/
		int nSample = series.size();
		double alpha = 2.0/(MA_period + 1);
		ArrayList<Double> movingAverage = new ArrayList<Double>();
		movingAverage.add(series.get(0));
		for (int i = 1; i < nSample; ++i)
			movingAverage.add(alpha*series.get(i) + (1-alpha)*movingAverage.get(movingAverage.size()-1));
		return movingAverage;
	}
	
	public static ArrayList<Double> SMA(ArrayList<Double> series, int MA_period)
	{
		ArrayList<Double> result = new ArrayList<Double>();
		for (int i = 0; i < series.size() - MA_period + 1; ++i)
		{
			double temp = 0;
			for (int j = i; j < (i + MA_period); ++j)
			{
				temp += series.get(j);
			}
			temp = temp / MA_period;
			result.add(temp);
		}
		return result;
	}
}
